package com.ocom.aiot.controller;


import com.github.pagehelper.PageInfo;
import com.ocom.aiot.service.XfDeviceInfoService;
import com.ocom.aiot.vo.consumedevice.AddDeviceInfoVo;
import com.ocom.aiot.vo.consumedevice.GetDeviceInfoVo;
import com.ocom.aiot.vo.consumedevice.SetDeviceStatusVo;
import com.ocom.aiot.vo.consumedevice.SetXfDeviceStatusBySaasVo;
import com.ocom.common.constant.AiotUrl;
import com.ocom.common.entity.aiot.EntityXfDeviceInfo;
import com.ocom.common.enums.ResultEnum;
import com.ocom.common.resp.Result;
import com.ocom.common.utils.DateUtils;
import com.ocom.common.utils.ResultUtil;
import com.ocom.common.utils.StringUtils;
import com.ocom.redis.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.*;

@Slf4j
@RestController
public class ConsumeDeviceController {

    @Autowired
    private XfDeviceInfoService xfDeviceInfoService;

    @Resource
    private RedisUtil redisUtil;

    // 2.3.1.获取设备信息（getDeviceInfo）
    @PostMapping(AiotUrl.URL_Aiot_GetDeviceInfo)
    public Result GetDeviceInfo(@Validated @RequestBody GetDeviceInfoVo getDeviceInfoVo){
        Map<String, Object> map = new HashMap<>();
        try {
            List<EntityXfDeviceInfo> entityXfDeviceInfos = xfDeviceInfoService.GetDeviceInfo(getDeviceInfoVo);
            entityXfDeviceInfos.forEach(item -> {
                item.setCommTime(getCommTime(item.getDeviceNo(),item.getCommTime()));
            });

            PageInfo<EntityXfDeviceInfo> entityXfDeviceInfoPageInfo = new PageInfo<>(entityXfDeviceInfos);
            map.put("total",entityXfDeviceInfoPageInfo.getTotal());
            map.put("list",entityXfDeviceInfos);

        }catch (Exception exception){
            log.error(exception.getMessage());
        }

        return ResultUtil.success(map);
    }

    // 2.3.2.添加设备信息（addDeviceInfo）
    @PostMapping(AiotUrl.URL_Aiot_AddDeviceInfo)
    public Result AddDeviceInfo(@Validated @RequestBody AddDeviceInfoVo addDeviceInfoVo){
        if (addDeviceInfoVo.getDeviceNo() == null){
            log.error("设备编号（出厂号）为空");
            return ResultUtil.error(ResultEnum.Err_203,"设备编号（出厂号）为空");
        }
        if (addDeviceInfoVo.getCommMode() == null){
            log.error("通讯协议为空");
            return ResultUtil.error(ResultEnum.Err_203,"通讯协议为空");
        }
        if (addDeviceInfoVo.getDeviceType() ==null){
            log.error("设备类型为空");
            return ResultUtil.error(ResultEnum.Err_203,"设备类型为空");
        }
        if (addDeviceInfoVo.getDeviceVerType() == null){
            log.error("设备机型为空");
            return ResultUtil.error(ResultEnum.Err_203,"设备机型为空");
        }
        try {
            EntityXfDeviceInfo entityXfDeviceInfo = xfDeviceInfoService.GetDeviceByDeviceNo(addDeviceInfoVo.getDeviceNo());
            List<String> list = new ArrayList<>();
            if (entityXfDeviceInfo != null){
                if (addDeviceInfoVo.getDeviceNo().equals(entityXfDeviceInfo.getDeviceNo())){
                    list.add(addDeviceInfoVo.getDeviceNo());
                    log.error("设备已存在，添加失败: "+list);
                    return ResultUtil.error(ResultEnum.Err_3003);
                }

            } else {
                try {
                    xfDeviceInfoService.AddDeviceInfo(addDeviceInfoVo);
                }catch (Exception exception){
                    log.error(exception.getMessage());
                    return ResultUtil.error(ResultEnum.Err_2009,exception.getMessage());
                }
            }
        }catch (Exception exception){
            log.error(exception.getMessage());
        }

        return ResultUtil.success();
    }


    // 2.3.3.修改设备信息（updateDeviceInfo）
    @PostMapping(AiotUrl.URL_Aiot_UpdateDeviceInfo)
    public Result UpdateDeviceInfo(@Validated @RequestBody EntityXfDeviceInfo entityXfDeviceInfo){
        if (entityXfDeviceInfo.getDeviceNo() == null ){
            log.error("设备编号（出厂号）为空: "+entityXfDeviceInfo.getDeviceNo());
            return ResultUtil.error(ResultEnum.Err_203,"设备编号（出厂号）为空");
        }


        try {
            xfDeviceInfoService.UpdateDeviceInfo(entityXfDeviceInfo);
        }catch (Exception exception){
            log.error("修改消费设备信息失败："+exception.getMessage());
            return ResultUtil.error(ResultEnum.Err_2009,"修改消费设备信息失败");
        }
        return ResultUtil.success();
    }

    //2.3.4.删除设备信息（deleteDeviceInfo）
    @PostMapping(AiotUrl.URL_Aiot_DeleteDeviceInfo)
    public Result DeleteDeviceInfo(@RequestParam("deviceNo") String deviceNo
                                     ,@RequestParam(required = false ,defaultValue = "0") Integer force){
        if (deviceNo == null ){
            log.error("设备编号参数为空");
            return ResultUtil.error(ResultEnum.Err_203,"设备编号参数为空");
        }

        try {
            EntityXfDeviceInfo xfDeviceInfo = xfDeviceInfoService.DeleteDeviceInfo(deviceNo,force);
            if (xfDeviceInfo!=null){
                log.error("删除失败，设备激活状态");
                return ResultUtil.error(ResultEnum.Err_3018,"删除失败，设备激活状态");
            }
        }catch (Exception exception){
            log.error(exception.getMessage());
            return ResultUtil.error(ResultEnum.Err_2009,exception.getMessage());
        }
        return ResultUtil.success();
    }

    // 2.4.5.SaaS平台设置设备状态（SetDeviceStatus）
    @PostMapping(AiotUrl.Url_Aiot_SetDeviceStatus)
    public Result SetDeviceStatus(@Validated @RequestBody SetDeviceStatusVo setDeviceStatusVo){
        log.info("AIOT 平台设置设备状态: "+setDeviceStatusVo);
        if (setDeviceStatusVo.getSaasNo().isEmpty()){
            log.error("saas平台绑定编号为空: "+setDeviceStatusVo);
            return ResultUtil.error(ResultEnum.Err_203,"saas平台绑定编号");
        }
        if (setDeviceStatusVo.getDeviceNo().isEmpty()){
            log.error("设备编号（出厂号）为空");
            return ResultUtil.error(ResultEnum.Err_203,"设备编号（出厂号）为空");
        }
//        if (setDeviceStatusVo.getComId() == null){
//            log.error("saas平台绑定单位id为空");
//            return ResultUtil.error(ResultEnum.Err_203,"saas平台绑定单位id为空");
//        }
        if (setDeviceStatusVo.getStatus() == null){
            log.error("启用状态为空");
            return ResultUtil.error(ResultEnum.Err_203,"启用状态为空");
        }
//        if (setDeviceStatusVo.getAgentId() == null){
//            log.error("saas平台绑定代理商id为空");
//            return ResultUtil.error(ResultEnum.Err_203,"saas平台绑定代理商id为空");
//        }
        try {
            xfDeviceInfoService.SetDeviceStatus(setDeviceStatusVo);
        }catch (Exception exception){
            log.error("SaaS平台设置设备状态更新操作失败");
            return ResultUtil.error(ResultEnum.Err_2009,"SaaS平台设置设备状态更新操作失败");
        }

        return ResultUtil.success();
    }

    // 3.2.SaaS平台激活(禁用)消费设备(SetXfDeviceStatusBySaas)
    @PostMapping(AiotUrl.Url_Aiot_SetXfDeviceStatusBySaas)
    public Result SetXfDeviceStatusBySaas(@Validated @RequestBody SetXfDeviceStatusBySaasVo setXfDeviceStatusBySaasVo){
        log.info("Aiot 设备激活 【{}】",setXfDeviceStatusBySaasVo);
        if (setXfDeviceStatusBySaasVo.getSaasNo().isEmpty()){
            log.error("Saas平台绑定编号参数为空 【{}】",setXfDeviceStatusBySaasVo);
            return ResultUtil.error(ResultEnum.Err_203,"Saas平台绑定编号参数为空");
        }
        if (setXfDeviceStatusBySaasVo.getComId()==null){
            log.error("单位编号参数为空【{}】",setXfDeviceStatusBySaasVo);
            return ResultUtil.error(ResultEnum.Err_203,"单位编号参数为空");
        }
        if (setXfDeviceStatusBySaasVo.getDeviceNo().isEmpty()){
            log.error("设备编号参数为空【{}】",setXfDeviceStatusBySaasVo);
            return ResultUtil.error(ResultEnum.Err_203,"设备编号参数为空");
        }

        EntityXfDeviceInfo entityXfDeviceInfo = null;
        try {
            entityXfDeviceInfo = xfDeviceInfoService.GetDeviceByDeviceNo(setXfDeviceStatusBySaasVo.getDeviceNo());
            if (entityXfDeviceInfo == null) {
                if(setXfDeviceStatusBySaasVo.getStatus() == 0){
                    return ResultUtil.success();
                }
                log.error("设备不存在【{}】",setXfDeviceStatusBySaasVo);
                return ResultUtil.error(ResultEnum.Err_2013);
            }
            if (setXfDeviceStatusBySaasVo.getStatus() == 0){
                if (entityXfDeviceInfo.getStatus() == 0) {
                    log.error("设备已注销【{}】",setXfDeviceStatusBySaasVo);
                    return ResultUtil.error(ResultEnum.Err_3022);
                }
                if (StringUtils.isNotNull(entityXfDeviceInfo.getPSaasNo()) && !setXfDeviceStatusBySaasVo.getSaasNo().equals(entityXfDeviceInfo.getPSaasNo())) {
                    log.error("设备已指定其他SaaS平台【{}】",setXfDeviceStatusBySaasVo);
                    return ResultUtil.error(ResultEnum.Err_3019);
                }
                if (StringUtils.isNull(entityXfDeviceInfo.getPComId())) {
                    if (StringUtils.isNotNull(entityXfDeviceInfo.getPAgentId()) && !setXfDeviceStatusBySaasVo.getAgentId().equals(entityXfDeviceInfo.getPAgentId())) {
                        log.error("设备已指定其他代理商【{}】",setXfDeviceStatusBySaasVo);
                        return ResultUtil.error(ResultEnum.Err_3020);
                    }
                }
                if(entityXfDeviceInfo.getPComId()!=0){
                    if (!setXfDeviceStatusBySaasVo.getComId().equals(entityXfDeviceInfo.getPComId())) {
                        log.error("设备已指定其他单位【{}】",setXfDeviceStatusBySaasVo);
                        return ResultUtil.error(ResultEnum.Err_3021);
                    }
                }

            }
            if (setXfDeviceStatusBySaasVo.getStatus() == 1) {
                if (entityXfDeviceInfo.getStatus() == 1) {
                    log.error("设备已激活【{}】",setXfDeviceStatusBySaasVo);
                    return ResultUtil.error(ResultEnum.Err_3018);
                }
                if (StringUtils.isNotNull(entityXfDeviceInfo.getPSaasNo()) && !setXfDeviceStatusBySaasVo.getSaasNo().equals(entityXfDeviceInfo.getPSaasNo())) {
                    log.error("设备已指定其他SaaS平台【{}】",setXfDeviceStatusBySaasVo);
                    return ResultUtil.error(ResultEnum.Err_3019);
                }
                if (StringUtils.isNull(entityXfDeviceInfo.getPComId())) {
                    if (StringUtils.isNotNull(entityXfDeviceInfo.getPAgentId()) && !setXfDeviceStatusBySaasVo.getAgentId().equals(entityXfDeviceInfo.getPAgentId())) {
                        log.error("设备已指定其他代理商【{}】",setXfDeviceStatusBySaasVo);
                        return ResultUtil.error(ResultEnum.Err_3020);
                    }
                }
                if(entityXfDeviceInfo.getPComId()!=0 && entityXfDeviceInfo.getPComId()!=null){
                    if (!setXfDeviceStatusBySaasVo.getComId().equals(entityXfDeviceInfo.getPComId())) {
                        log.error("设备已指定其他单位【{}】",setXfDeviceStatusBySaasVo);
                        return ResultUtil.error(ResultEnum.Err_3021);
                    }
                }

            }
        } catch (Exception exception) {
            log.error("SaaS平台获取设备信息失败 【{}】 【{}】", exception , setXfDeviceStatusBySaasVo);
            return ResultUtil.error(ResultEnum.Err_2009, "SaaS平台获取设备信息失败");
        }
        SetDeviceStatusVo setDeviceStatusVo = new SetDeviceStatusVo();
        setDeviceStatusVo.setDeviceNo(setXfDeviceStatusBySaasVo.getDeviceNo());
        setDeviceStatusVo.setComId(setXfDeviceStatusBySaasVo.getComId());
        if (setXfDeviceStatusBySaasVo.getAgentId()!=null){
            setDeviceStatusVo.setAgentId(setXfDeviceStatusBySaasVo.getAgentId());
        }
        setDeviceStatusVo.setSaasNo(setXfDeviceStatusBySaasVo.getSaasNo());
        setDeviceStatusVo.setStatus(setXfDeviceStatusBySaasVo.getStatus());
        this.SetDeviceStatus(setDeviceStatusVo);

        return ResultUtil.success(entityXfDeviceInfo);
    }

    @PostMapping(AiotUrl.Url_Aiot_getDeviceInfoByMachNo)
    public Result getDeviceInfoByMachNo(String machNo){
        EntityXfDeviceInfo entityXfDeviceInfo = xfDeviceInfoService.GetDeviceByDeviceNo(machNo);
        if(entityXfDeviceInfo == null){
            return ResultUtil.error(ResultEnum.Err_3007);
        }
        return ResultUtil.success(entityXfDeviceInfo);
    }


    private Date getCommTime(String machNo, Date commTime){
        Object obj = redisUtil.get("HttpAiotMachCommTime:"+machNo);
        if(obj!=null){
            return (Date) obj;
        }
        if(commTime==null){
            commTime = DateUtils.strToDate("2020-01-01 12:34:56");
        }
        redisUtil.set("HttpAiotMachCommTime:"+machNo,commTime);
        return commTime;
    }

}
